/**
 * @file list.h
 * @author 玄绮 (shijiahansi@qq.com)
 * @brief 
 * @version 0.1
 * @date 2021-06-25
 * 
 * @copyright Copyright (c) 2021
 * 
 */
#ifndef __LIST_H__
#define __LIST_H__
#include "ds_common.h"

typedef struct List List;
typedef List *PList;
typedef const List *CPList;

typedef struct List_Node List_Node;
typedef List_Node *PList_Node;
typedef const List_Node *CPList_Node;

struct List_Node
{
    PList_Node prev;
    PList_Node next;
    PData_Val data;
};


//交换两个节点的位置
void list_node_swap(PList_Node node_r, PList_Node node_f);

//绑定用于比较两个元素是否相等的函数
//若两个参数相等，equal应返回true
void list_bind_equal(PList thisc, bool (*equal)(PData_Val, PData_Val));

//绑定用于比较两个元素的大小的函数
//若第一个参数小于第二个参数，less应返回true
void list_bind_less(PList thisc, bool (*less)(PData_Val, PData_Val));

//创建并返回一个双向链表
PList list_creat(int sizeof_type);

//销毁链表
void list_destory(PList thisc);

//返回指向容器中第一个元素的双向迭代器。
PList_Node list_begin(PList thisc);

//返回指向容器中最后一个元素所在位置的双向迭代器。
PList_Node list_end(PList thisc);

//和 begin() 功能相同，只不过在其基础上，增加了 const 属性，不能用于修改元素。
CPList_Node list_cbegin(PList thisc);

//和 end() 功能相同，只不过在其基础上，增加了 const 属性，不能用于修改元素。
CPList_Node list_cend(PList thisc);

//判断容器中是否有元素，若无元素，则返回 true；反之，返回 false。
bool list_empty(PList thisc);

//返回当前容器实际包含的元素个数。
size_t list_size(PList thisc);

//返回第一个元素的引用。
CPData_Val list_front(PList thisc);

//返回最后一个元素的引用。
CPData_Val list_back(PList thisc);

//在容器头部插入一个元素。
void list_push_front(PList thisc, CPData_Val data);

//在容器尾部插入一个元素。
void list_push_back(PList thisc, CPData_Val data);

//删除容器头部的一个元素。
void list_pop_front(PList thisc);

//删除容器尾部的一个元素。
void list_pop_back(PList thisc);

//在容器中的指定位置前插入元素。
void list_insert(PList thisc, PList_Node location, CPData_Val data);

//删除容器中一个元素。
void list_erase(PList thisc, PList_Node location);

//删除容器中某区域内的元素。
void list_erase_as(PList thisc, PList_Node begin, PList_Node end);

//删除容器中所有等于 val 的元素。
//使用前应调用list_bind_equal()函数绑定比较函数
void list_remove(PList thisc, PData_Val val);

//删除容器中满足条件的元素。
void list_remove_if(PList thisc, bool (*factor)(PData_Val));

//删除容器中相邻的重复元素，只保留一个。
//使用前应调用list_bind_equal()函数绑定比较函数
void list_unique(PList thisc);

//合并两个事先已排好序的 list 容器，并且合并之后的 list 容器依然是有序的。
//使用前应调用list_bind_less()函数绑定比较函数
PList list_merge(PList list_r, PList list_f);

//通过更改容器中元素的位置，将它们进行排序。
//使用前应调用list_bind_less()函数绑定比较函数
void list_sort(PList thsic);

//反转容器中元素的顺序。
void list_reverse(PList thisc);

//反转容器中元素的顺序。
void list_reverse1(PList thisc);

#endif //__LIST_H__